package com.yunc.base.schedule;

import cn.hutool.core.bean.BeanUtil;
import com.yunc.base.utils.ScheduleConstant;
import com.yunc.base.utils.SpringContextUtils;
import com.yunc.modules.quartz.entity.SysJob;
import com.yunc.modules.quartz.entity.SysJobLog;
import com.yunc.modules.quartz.service.ISysJobLogService;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;

/**
 * 扩展job
 * Quartz定时任务默认都是并发执行的，不会等待上一次任务执行完毕，只要间隔时间到就会执行, 如果定时任执行太长，会长时间占用资源，导致其它任务堵塞
 * @DisallowConcurrentExecution 禁止并发执行,程序会等之前任务执行完毕以后再去执行
 *
 * @author congcong tao
 * @date 2018/11/10 10:27
 */
public abstract class AbstractScheduleJob implements Job {

    private static final Logger logger = LoggerFactory.getLogger(AbstractScheduleJob.class);

    /**
     * 线程本地变量
     */
    private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();

    public void before(JobExecutionContext context) {
        threadLocal.set(new Date());
    }

    public abstract void doWork(JobExecutionContext context, SysJob sysJob) throws Exception;

    public void after(JobExecutionContext context) {

    }

    @Override
    public void execute(JobExecutionContext context) {
        ISysJobLogService sysJobLogService = (ISysJobLogService) SpringContextUtils.getBean("sysJobLogService");
        // 开始时间
        // String startTime = DateUtil.formatDateTime(new Date());
        SysJob sysJob = new SysJob();
        BeanUtil.copyProperties(context.getMergedJobDataMap().get(ScheduleConstant.TASK_PROPERTIES), sysJob);
        String name = context.getTrigger().getJobKey().getName();
        SysJobLog jobLog = new SysJobLog();
        jobLog.setJobName(sysJob.getJobName());
        jobLog.setJobGroup(sysJob.getJobGroup());
        jobLog.setMethodName(sysJob.getClassName() + "." + sysJob.getMethodName() + "()");
        jobLog.setCreateTime(new Date());
        before(context);
        Date startTime = threadLocal.get();
        threadLocal.remove();
        try {
            // 执行成功
            doWork(context, sysJob);
            long times = System.currentTimeMillis() - startTime.getTime();
            // 任务状态 0：成功 1：失败
            jobLog.setIsException("0");
            jobLog.setJobMessage(sysJob.getJobName() + " 总共耗时：" + times + "毫秒");
        } catch (Exception e) {
            long times = System.currentTimeMillis() - startTime.getTime();
            logger.info("未查询到任务,任务名:{}，时间:{}", name, new Date());
            jobLog.setJobMessage(sysJob.getJobName() + " 总共耗时：" + times + "毫秒");
            // 任务状态 0：成功 1：失败
            jobLog.setIsException("1");
            jobLog.setExceptionInfo(e.toString());
        } finally {
            sysJobLogService.save(jobLog);
        }
        after(context);
    }
}
